/**
 * Copyright (c) 2009  Collaborative Development Group, C.S. Dept., University of Bari
 *
 * All rights reserved. This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License v1.0  which accompanies this distribution, and is 
 * available at http://www.eclipse.org/legal/epl-v10.html
 */
package it.uniba.di.cdg.jtalk.ui.login;

import static it.uniba.di.cdg.jtalk.ui.login.ILoginPresentationModel.PASSWORD_PROPERTY;
import static it.uniba.di.cdg.jtalk.ui.login.ILoginPresentationModel.USER_ID_PROPERTY;
import static it.uniba.di.cdg.penelope.presenterfirst.TestHelpers.mockChangeEvent;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import it.uniba.di.cdg.jtalk.core.LoginFailedException;
import it.uniba.di.cdg.jtalk.ui.login.ILoginView.LogInButtonClicked;
import it.uniba.di.cdg.penelope.presenterfirst.SUT;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

/**
 * GUI BDD Tests for User Story #5.
 */
@RunWith( MockitoJUnitRunner.class ) 
public class LoginToServerGUIStoryTest {
	private static final String USERID = "pippo@gmail.com";
	private static final String PASSWORD = "pass";
	
	@Mock
	private ILoginView view;
	@Mock
	private ILoginPresentationModel presentationModel;	
	@Mock
	private ILoginModel model;
	
	@SUT
	private LoginPresenter presenter;

	@Before
	public void createSUT() {
		presenter = new LoginPresenter( view, presentationModel, model );
	}

	@Test
	public void whenViewIsCreatedUpdateAccordingToPresentationModel() {
		// given the presentation model contains empty username and password initially 
		given( presentationModel.getUserId() ).willReturn( "" );
		given( presentationModel.getPassword() ).willReturn( "" );
		
		// when view is started
		presenter.onViewCreated();
		
		// then the view button is disabled
		verify( view ).enableLoginButton( false );
	}
	
	
	@Test
	public void whenLoginClickedAuthenticateToServer() {
		//given user name and password are correctly populated
		given( presentationModel.getUserId() ).willReturn( USERID );
		given( presentationModel.getPassword() ).willReturn( PASSWORD );
		
		//when 
		presenter.whenLogInButtonClicked( new LogInButtonClicked() );

		//then
		verify( model ).logIn( USERID, PASSWORD, false, false );
		verify( view ).enableUserInput( false );
		verify( view, never() ).showError( anyString() );
	}
	
	@Test
	public void whenAnErrorOccursDuringLoggingInShowMessage() {
		//given that login will fail with the current userid and password
		given( presentationModel.getUserId() ).willReturn( USERID );
		given( presentationModel.getPassword() ).willReturn( PASSWORD );
		doThrow( new LoginFailedException( "Mock Login Exception" ) )
			.when( model ).logIn( USERID, PASSWORD, false, false );

		//when log in button clicked
		presenter.whenLogInButtonClicked( new LogInButtonClicked() );

		//then ensure that login was requested and an error displayed
		verify( model ).logIn( USERID, PASSWORD, false, false );
		verify( view ).showError( anyString() );
	}

	@Test
	public void whenUserIdFieldIsEmptyDisableLoginButton() {
		//given blank user id
		given( presentationModel.getUserId() ).willReturn( "" );
		given( presentationModel.getPassword() ).willReturn( PASSWORD );
		
		//when view updates the presentation model
		presenter.propertyChange( mockChangeEvent( presentationModel, USER_ID_PROPERTY, "", "" ) );
		
		//then
		verify( view ).enableLoginButton( false );
	}
	
	@Test
	public void whenPasswordFieldIsEmptyDisableLoginButton() {
		//given blank password
		given( presentationModel.getUserId() ).willReturn( USERID );
		given( presentationModel.getPassword() ).willReturn( "" );

		//when view updates the presentation model 
		presenter.propertyChange( mockChangeEvent( presentationModel, PASSWORD_PROPERTY, "", "" ) );
		
		//then login button is disabled by the presenter
		verify( view ).enableLoginButton( false );
	}
}
